package qc.module.cms.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import qc.common.core.constants.QCAuthConstant;
import qc.common.core.enums.CmsArticleOperateTypeEnum;
import qc.common.core.exception.QCPromptException;
import qc.module.cms.dto.article.*;
import qc.module.cms.service.ArticleLogService;
import qc.module.cms.service.ArticleService;
import qc.module.platform.dto.dept.DeptSimpleDto;
import qc.module.platform.dto.uac.UacUserInfoDto;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ArticleController
 *
 * @author QuCheng Tech
 * @create 2023/5/26
 */
@RestController
@RequestMapping("/article")
public class ArticleController {
    private ArticleService articleService;

    @Autowired
    public void setArticleService(ArticleService articleService) {
        this.articleService = articleService;
    }

    private ArticleLogService articleLogService;

    @Autowired
    public void setArticleLogService(ArticleLogService articleLogService) {
        this.articleLogService = articleLogService;
    }

    //是否为逻辑删除，为true表示逻辑删除--修改记录标记，为false表示物理删除--从数据库表中删除记录
    private static final boolean isLogicDelete = false;

    @Autowired
    HttpServletRequest request;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 查询文章列表，根据用户所在部门过滤筛选；返回结果中不包含文章的内容。
     *
     * @param condition 查询条件
     * @return 查询结果，包含分页信息和文章列表，文章不包含内容信息
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/query", method = {RequestMethod.GET, RequestMethod.POST})
    public ArticleQueryResultDto query(@RequestBody ArticleQueryConditionDto condition) throws QCPromptException {
        List<Integer> userDeptIds = null;
        //获取当前用户的部门信息，供查询时作为栏目过滤条件使用
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        List<DeptSimpleDto> userDepts = getUserValidDepts(token);
        if (userDepts != null && userDepts.size() > 0x0) {
            userDeptIds = userDepts.stream().map(p -> p.getId()).collect(Collectors.toList());
        }

        return articleService.query(condition, userDeptIds);
    }

    /**
     * 根据用户所在部门，部门管理的栏目进行过滤筛选；返回结果中不包含文章的内容。
     *
     * @return 待审核文章列表，文章不包含内容信息
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/queryaudit", method = {RequestMethod.GET, RequestMethod.POST})
    public ArticleQueryResultDto getAudit(@RequestBody ArticleQueryConditionDto condition) throws QCPromptException {
        List<Integer> userDeptIds = null;
        //获取当前用户的部门信息，供查询时作为栏目过滤条件使用
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        List<DeptSimpleDto> userDepts = getUserValidDepts(token);
        if (userDepts != null && userDepts.size() > 0x0) {
            userDeptIds = userDepts.stream().map(p -> p.getId()).collect(Collectors.toList());
        }

        return articleService.getNeedAudit(condition, userDeptIds);
    }

    /**
     * 查询敏感词匹配的文章，返回结果中包含匹配的敏感词信息
     * 
     * @param condition 查询条件
     * @return List<ArticleDto>
     * @author QcCheng Tech
     * @since 2024/4/28
     */
    @RequestMapping(value = "/querysensitivewords", method = {RequestMethod.GET, RequestMethod.POST})
    public List<ArticleDto> queryBySensitiveWords(@RequestBody SensitiveWordsQueryConditionDto condition){
        return articleService.queryBySensitiveWords(condition);
    }

    /**
     * 敏感词替换
     *
     * @param dto 查询条件
     * @return 成功返回null，失败返回提示信息
     * @author QcCheng Tech
     * @since 2024/4/29
     */
    @RequestMapping(value = "/replacesensitivewords",method = {RequestMethod.GET,RequestMethod.POST})
    public String replaceSensitiveWords(@RequestBody ReplaceSensitiveWordsDto dto) {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);
        
        return articleService.replaceSensitiveWords(dto,userInfo);
    }

    /**
     * 根据token获取用户所在的有效的部门
     *
     * @param token 用户登录得到的Token
     * @return 部门简要信息集合
     * @author QuCheng Tech
     * @since 2023/5/31
     */
    public List<DeptSimpleDto> getUserValidDepts(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, token);

        ServiceInstance service = discoveryClient.getInstances("module-platform").get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/dept/uservalid";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<List<DeptSimpleDto>> responseType = new ParameterizedTypeReference<List<DeptSimpleDto>>() {
        };

        ResponseEntity<List<DeptSimpleDto>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<DeptSimpleDto> resultDto = response.getBody();

        return resultDto;
    }

    /**
     * 根据token获取用户信息
     *
     * @param token 用户登录得到的Token
     * @return 用户
     * @author QuCheng Tech
     * @since 2023/5/31
     */
    public UacUserInfoDto getUserInfo(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, token);

        ServiceInstance service = discoveryClient.getInstances("module-platform").get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/uac/userinfo";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<UacUserInfoDto> responseType = new ParameterizedTypeReference<UacUserInfoDto>() {
        };

        ResponseEntity<UacUserInfoDto> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        UacUserInfoDto resultDto = response.getBody();

        return resultDto;
    }

    /**
     * 获取指定文章信息
     *
     * @param id 文章ID
     * @return 文章信息
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/get", method = {RequestMethod.GET})
    public ArticleDto getByParam(@RequestParam int id) throws QCPromptException {
        return articleService.get(id);
    }

    /**
     * 获取指定文章信息
     *
     * @param id 文章ID
     * @return 文章信息
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/get/{id}", method = {RequestMethod.GET})
    public ArticleDto getByPath(@PathVariable(required = true) int id) throws QCPromptException {
        return articleService.get(id);
    }

    /**
     * 文章保存为草稿
     *
     * @param dto 文章信息，可以指定ID表示修改，不指定ID表示新增
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/save", method = {RequestMethod.POST})
    public String save(@RequestBody ArticleSaveDto dto) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.save(dto, userInfo);
    }

    /**
     * 文章操作--提交审核
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/audit", method = {RequestMethod.POST})
    public String auditByParam(@RequestParam int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.AUDIT, null, userInfo);
    }

    /**
     * 文章操作--提交审核
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/audit/{id}", method = {RequestMethod.POST})
    public String auditByPath(@PathVariable(required = true) int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.AUDIT, null, userInfo);
    }

    /**
     * 文章操作--审核通过   直接发布
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/pass", method = {RequestMethod.POST})
    public String passByParam(@RequestParam int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.PASS, null, userInfo);
    }

    /**
     * 文章操作--审核通过  直接发布
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/pass/{id}", method = {RequestMethod.POST})
    public String pass(@PathVariable(required = true) int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.PASS, null, userInfo);
    }

    /**
     * 文章操作--审核不通过
     *
     * @param dto 操作信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/nopass", method = {RequestMethod.POST})
    public String nopassByPath(@RequestBody ArticleOperateDto dto) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(dto.getId(), CmsArticleOperateTypeEnum.NO_PASS, dto.getMsg(), userInfo);
    }

    /**
     * 文章操作--发布
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/publish", method = {RequestMethod.POST})
    public String publishByParam(@RequestParam int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.PUBLISH, null, userInfo);
    }

    /**
     * 文章操作--发布
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/publish/{id}", method = {RequestMethod.POST})
    public String publishByPath(@PathVariable(required = true) int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.PUBLISH, null, userInfo);
    }

    /**
     * 文章操作--发布撤回
     *
     * @param dto 操作信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/recall", method = {RequestMethod.POST})
    public String recall(@RequestBody ArticleOperateDto dto) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(dto.getId(), CmsArticleOperateTypeEnum.RECALL, dto.getMsg(), userInfo);
    }

    /**
     * 文章操作--删除
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/delete", method = {RequestMethod.POST})
    public String deleteByParam(@RequestParam int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        if (isLogicDelete)
            return articleService.operate(id, CmsArticleOperateTypeEnum.DELETED, null, userInfo);
        else
            return articleService.delete(id);
    }

    /**
     * 文章操作--删除
     *
     * @param id 文章ID
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/delete/{id}", method = {RequestMethod.POST})
    public String deleteByPath(@PathVariable(required = true) int id) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(id, CmsArticleOperateTypeEnum.DELETED, null, userInfo);
    }

    /**
     * 文章操作--设置标签
     *
     * @param dto 操作信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/addtag", method = {RequestMethod.POST})
    public String addTag(@RequestBody ArticleOperateDto dto) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(dto.getId(), CmsArticleOperateTypeEnum.SET_TAG, dto.getMsg(), userInfo);
    }

    /**
     * 文章操作--取消标签
     *
     * @param dto 操作信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/removetag", method = {RequestMethod.POST})
    public String removeTag(@RequestBody ArticleOperateDto dto) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(dto.getId(), CmsArticleOperateTypeEnum.CANCEL_TAG, dto.getMsg(), userInfo);
    }

    /**
     * 文章操作
     *
     * @param dto 文章操作信息
     * @return 成功返回null
     * @author QuCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/operate", method = {RequestMethod.POST})
    public String operate(@RequestBody ArticleOperateDto dto) throws QCPromptException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        return articleService.operate(dto.getId(), CmsArticleOperateTypeEnum.DRAFT, dto.getMsg(), userInfo);
    }

    /**
     * 查看指定文章信息，查看时自动将次数+1
     *
     * @param id 文章ID
     * @return 文章信息
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/view", method = {RequestMethod.GET})
    public ArticleDto viewByParam(@RequestParam int id) throws QCPromptException {
        return articleService.view(id);
    }

    /**
     * 查看指定文章信息，查看时自动将次数+1
     *
     * @param id 文章ID
     * @return 文章信息
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/view/{id}", method = {RequestMethod.GET})
    public ArticleDto viewByPath(@PathVariable(required = true) int id) throws QCPromptException {
        return articleService.view(id);
    }

    /**
     * 查看指定文章操作日志
     *
     * @param id 文章ID
     * @return 日志集合
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/logs", method = {RequestMethod.GET})
    public List<ArticleLogDto> logsByParam(@RequestParam int id) throws QCPromptException {
        return articleLogService.getArticleLogs(id);
    }

    /**
     * 查看指定文章操作日志
     *
     * @param id 文章ID
     * @return 日志集合
     * @author QcCheng Tech
     * @since 2023/5/29
     */
    @RequestMapping(value = "/logs/{id}", method = {RequestMethod.GET})
    public List<ArticleLogDto> logsByPath(@PathVariable(required = true) int id) throws QCPromptException {
        return articleLogService.getArticleLogs(id);
    }

    /**
     * 移动文章到指定栏目
     *
     * @param dto:操作信息
     * @return String 成功返回null，失败返回错误信息
     * @author QcCheng Tech
     * @date 2023/10/23
     */
    @RequestMapping(value = "/movetocategory", method = {RequestMethod.POST})
    public String moveToCategory(@RequestBody MoveToCategoryDto dto) throws QCPromptException {
        return articleService.moveToCategory(dto);
    }


}
